package com.acme.exchange.network.proto;

import java.math.BigDecimal;

import com.acme.exchange.domain.order.Order;
import com.acme.exchange.exception.IllegalExchangeMessageData;
import com.acme.exchange.network.proto.Protocol.ExchangeMessage;
import com.acme.exchange.network.proto.Protocol.ExchangeMessage.MessageType;
import com.acme.exchange.network.proto.Protocol.ExchangeMessage.OrderStatus;
import com.acme.exchange.network.proto.Protocol.ExchangeMessage.OrderType;
import com.acme.exchange.network.proto.Protocol.ExchangeMessage.Side;

public class MessageConstructor {

	public static ExchangeMessage constructNewOrder(int clOrderId,
			OrderType ot, Side s, String ticker, int quantity, String price){
		
		//new order			
		ExchangeMessage newOrder = ExchangeMessage.newBuilder()
				.setMessageType(MessageType.NEW_ORDER)
				.setClientOrderId(clOrderId)
				.setOrderType(ot)
				.setSide(s)
				.setSymbol(ticker)
				.setQuantity(quantity)
				.setPrice(price)
				.build();
		return newOrder;
	}

	public static ExchangeMessage constructExecutionReport(int clOrderId,
			OrderStatus os, int quantity, String price) {

		//Execution report		
		ExchangeMessage newOrder = ExchangeMessage.newBuilder()
				.setMessageType(MessageType.EXECUTION_REPORT)
				.setClientOrderId(clOrderId)				
				.setOrderStatus(os)
				.setCumulativeQuantity(quantity)
				.setPrice(price).build();
		return newOrder;
	}
	
	public static ExchangeMessage constructExecutionReportForNewOrder(Order order, String ticker) {

		//Execution report	
		ExchangeMessage newOrder;
		if (order.getOrderType() == OrderType.LIMIT){
				newOrder = ExchangeMessage.newBuilder()
					.setMessageType(MessageType.EXECUTION_REPORT)
					.setClientOrderId(order.getClientOderID())	
					.setOrderType(OrderType.LIMIT)
					.setSide(order.getOpType())					
					.setOrderStatus(OrderStatus.NEW)
					.setOrderId(order.getOderID())
					.setSymbol(ticker)
					.setQuantity(order.getVolume())
					.setUsername(order.getClientLogin())
					.setPrice(order.getPrice().toString())					
					.build();
		}else {
				newOrder = ExchangeMessage.newBuilder()
					.setMessageType(MessageType.EXECUTION_REPORT)
					.setClientOrderId(order.getClientOderID())
					.setOrderType(OrderType.MARKET)
					.setSide(order.getOpType())
					.setOrderId(order.getOderID())
					.setSymbol(ticker)
					.setOrderStatus(OrderStatus.NEW)
					.setQuantity(order.getVolume())	
					.setUsername(order.getClientLogin())
					.build();
		}
		
		return newOrder;
	}
	
	public static ExchangeMessage constructExecutionReport(Order order, OrderStatus os, BigDecimal mPrice, int quantity, String counterparty) {

		//Execution report		
		ExchangeMessage newOrder = ExchangeMessage.newBuilder()
				.setMessageType(MessageType.EXECUTION_REPORT)
				.setClientOrderId(order.getClientOderID())				
				.setOrderStatus(os)
				.setCumulativeQuantity(quantity)
				.setLastPrice(mPrice.toString())
				.setUsername(order.getClientLogin())
				.setCounterparty(counterparty)				
				.build();
		return newOrder;
	}
	
	public static ExchangeMessage constructExecutionReportReject(int clOrderId,
			String rr) throws IllegalExchangeMessageData {

		//reject		
		ExchangeMessage newOrder = ExchangeMessage.newBuilder()
				.setMessageType(MessageType.EXECUTION_REPORT)
				.setClientOrderId(clOrderId)
				.setOrderStatus(OrderStatus.REJECTED)				
				.setComment(rr)
				.build();
		return newOrder;
	}
	
	public static ExchangeMessage constructLoginMessage(String login) {

		//logon		
		ExchangeMessage newOrder = ExchangeMessage.newBuilder()
				.setMessageType(MessageType.LOGON)
				.setUsername(login)
				.build();
		return newOrder;
	}
	
	public static ExchangeMessage constructRejectMessage(String rejectReason) {

		//Reject
		
		ExchangeMessage newOrder = ExchangeMessage.newBuilder()
				.setMessageType(MessageType.REJECT)
				.setComment(rejectReason)
				.build();
		return newOrder;
	}
	
}
